package com.learn.LR1Analysis;

import lombok.Data;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Data
public class LR1 {
    private List<String> nonTerminals=new ArrayList<String>();//非终结符集合
    private List<String> terminals=new ArrayList<String>();//终结符集合
    private List<ArrayList<String>> productions=new ArrayList<ArrayList<String>>();//产生式集合
    private List<ArrayList<String>> pros=new ArrayList<ArrayList<String>>();//产生式集合
    List<String> conbine=new ArrayList<String>();//combine存储所有的文法符号（非终结符+终结符）
    private String start=null;//开始符号
    String[][] a=new String[255][255];//分析表
    int countE=0;//为临时变量的下标命名的指针
    int pointer=0;//三地址码的行数
    int countQuaternion=0;//用来记录四元式的下标


    //更改开始
    SymbolStack symbolStack = new SymbolStack();
    List<ArrayList<String>> ternaryFormulas=new ArrayList<ArrayList<String>>();//三地址码集合

    /**
     * 回填函数，用以回填地址
     * @param listHead
     * @param input
     */
    public void backPatch(int listHead,int input){
        if(listHead==-1){
            return;
        }
        String newListHead;
        if(ternaryFormulas.get(listHead).size()==5){
            newListHead=ternaryFormulas.get(listHead).get(4);
            ternaryFormulas.get(listHead).set(4,String.valueOf(input));
            backPatch(Integer.parseInt(newListHead),input);
        }
        else {
            newListHead=ternaryFormulas.get(listHead).get(2);
            ternaryFormulas.get(listHead).set(2,String.valueOf(input));
            backPatch(Integer.parseInt(newListHead),input);
        }
    }

    /**
     * 合并两条链，并返回链首
     * @param fristList
     * @param secondList
     * @return
     */
    public int merge(int fristList,int secondList){

        dfsForMerge(fristList,secondList);

        return fristList;
    }


    public void dfsForMerge(int fri,int sec){

        ArrayList<String> quaternion = ternaryFormulas.get(fri);
        if(quaternion.size()==5){
            if(Objects.equals(quaternion.get(4), String.valueOf(-1))){
                quaternion.set(4,String.valueOf(sec));
                return;
            }else {
                int next=Integer.parseInt(quaternion.get(4));
                dfsForMerge(next,sec);
            }
        }
        if(quaternion.size()==3){
            if(Objects.equals(quaternion.get(2), String.valueOf(-1))){
                quaternion.set(2,String.valueOf(sec));
                return;
            }else {
                int next=Integer.parseInt(quaternion.get(2));
                dfsForMerge(next,sec);
            }
        }

    }

    //更改结束

    public LR1() {
        // TODO Auto-generated constructor stub
    }
    public void analyse(String str) {
        initAnalysisTable();//先初始化分析表
        //输出分析表
        System.out.println("*******************分析表************************");
        for(int i=0;i<255;i++) {
            for(int j=0;j<255;j++) {
                if(a[i][j]!=null) {
                    System.out.println(i+"+"+conbine.get(j)+"->"+a[i][j]);
                }
            }
        }

        Stack state=new Stack();//状态栈
        Stack analysis =new Stack();//符号栈
        state.push("0");
        analysis.push("#");

        int tt=0,i=0;//tt记录步骤次数，i记录句子指针位置
        String firstChar=str.substring(i,i+1);
        int m = Integer.parseInt(state.getTopObjcet());
        int n = conbine.indexOf(firstChar);
        //如果输入符号中含有非法符号，即不属于当前文法的文法符号集合，提示并终止程序
        if(n==-1) {
            System.out.println("出错了！！！输入符号中含有非法符号");
            return;
        }
        //System.out.println(conbine);
        while(a[m][n]!="acc") {
            System.out.println("************步骤"+(++tt)+"*************");
            System.out.print("状态栈：");
            state.output();
            System.out.print("符号栈：");
            analysis.output();
            System.out.print("输入串：");
            System.out.println(str.substring(i));
            System.out.print("执行动作：");
            System.out.print("ACTION["+m+","+firstChar+"]="+a[m][n]+"    ");
            if(a[m][n]==null) {
                System.out.println("出错了！！！该句子语法错误");
                break;
            }else if(a[m][n].startsWith("S")) {
                //System.out.println(a[m][n].substring(1, a[m][n].length()));
                state.push(a[m][n].substring(1, a[m][n].length()));
                analysis.push(firstChar);
                System.out.println("\nACTION["+m+","+firstChar+"]="+a[m][n]+",移进"+firstChar+"，状态"+a[m][n].substring(1, a[m][n].length())+"入栈");

                //改动部分开始
                Symbol symbol=new Symbol();
                symbol.setVal(firstChar);
                symbolStack.push(symbol);
                //改动部分结束

                firstChar=str.substring(++i,i+1);



            }else if(a[m][n].startsWith("r")) {
                int loc = Integer.parseInt(a[m][n].substring(1, a[m][n].length()));
                ArrayList<String> pp = productions.get(loc);
                String mm="";
                String nn="";
                for(int j=0;j<pp.size()-1;j++) {
                    mm+=state.pop();
                    nn+=analysis.pop();
                }
                analysis.push(pp.get(0));

                /**
                 * 0[S', S]
                 * 1[S, d, s]
                 * 2[d, W, E, o]
                 * 3[W, w]
                 * 4[E, E, <, E]
                 * 5[E, E, >, E]
                 * 6[E, i]
                 * 7[s, i, =, E]
                 * 8[E, E, +, E]
                 * 9[E, E, -, E]
                 * 10[E, E, O, E]
                 * 11[E, E, A, E]
                 * 12[E, N, E]
                 * 13[s, s, ;, s]
                 * 14[E, (, E, )]
                 * 15[E,j]
                 * 16[E,k]
                 * 17[E,l]
                 * 18[E,m]
                 * 19[E,n]
                 * 20[s,d,s]
                 */

                Symbol symbol=new Symbol();
                ArrayList<String> list=new ArrayList<>();

                //System.out.println("=====");
                if(loc==1||loc==20){
                    Symbol sSymbol=symbolStack.pop();
                    Symbol dSymbol=symbolStack.pop();

                    backPatch(sSymbol.getChain(),dSymbol.getBeginCode());
                    list.add(String.valueOf(countQuaternion));
                    list.add("goto");
                    list.add(String.valueOf(dSymbol.getBeginCode()));
                    ternaryFormulas.add(list);

                    //四元式数量自增1
                    countQuaternion++;

                    backPatch(dSymbol.getFalseList(),countQuaternion);
                }
                if(loc==2){
                    symbolStack.pop();
                    Symbol ESymbol=symbolStack.pop();
                    Symbol WSymbol=symbolStack.pop();

                    String name="d"+countE;
                    countE++;
                    symbol.setVal(name);
                    //symbol.setPlace(String.valueOf(pointer));
                    pointer++;

                    //将新属性入栈
                    backPatch(ESymbol.getTrueList(),countQuaternion);
                    symbol.setChain(ESymbol.getFalseList());
                    symbol.setBeginCode(WSymbol.getBeginCode());
                    symbol.setFalseList(ESymbol.getFalseList());
                    symbolStack.push(symbol);

                }
                if(loc==3){
                    Symbol wSymbol=symbolStack.pop();

                    String name="W"+countE;
                    countE++;
                    symbol.setVal(name);
                    //symbol.setPlace(String.valueOf(pointer));
                    pointer++;

                    symbol.setBeginCode(countQuaternion);

                    //将新属性入栈
                    symbolStack.push(symbol);

                }
                if(loc==4){
                    Symbol E2Symbol=symbolStack.pop();
                    symbolStack.pop();
                    Symbol E1Symbol=symbolStack.pop();

                    String name="E"+countE;
                    countE++;
                    symbol.setVal(name);
                    //symbol.setPlace(String.valueOf(pointer));
                    pointer++;

                    symbol.setTrueList(countQuaternion);
                    symbol.setFalseList(countQuaternion+1);
                    symbol.setBeginCode(countQuaternion);

                    //将新属性入栈
                    symbolStack.push(symbol);

                    list.add(String.valueOf(countQuaternion));
                    list.add("if");
                    list.add(E1Symbol.val+"<"+E2Symbol.val);
                    list.add("goto");
                    list.add("-1");
                    ternaryFormulas.add(list);

                    //四元式数量自增1
                    countQuaternion++;

                    list=new ArrayList<>();
                    list.add(String.valueOf(countQuaternion));
                    list.add("goto");
                    list.add("-1");
                    ternaryFormulas.add(list);

                    //四元式数量自增1
                    countQuaternion++;
                }
                if(loc==5){
                    Symbol E2Symbol=symbolStack.pop();
                    symbolStack.pop();
                    Symbol E1Symbol=symbolStack.pop();

                    String name="T"+countE;
                    countE++;
                    symbol.setVal(name);
                    //symbol.setPlace(String.valueOf(pointer));
                    pointer++;

                    symbol.setTrueList(countQuaternion);
                    symbol.setFalseList(countQuaternion+1);
                    symbol.setBeginCode(countQuaternion);

                    //将新属性入栈
                    symbolStack.push(symbol);

                    list.add(String.valueOf(countQuaternion));
                    list.add("if");
                    list.add(E1Symbol.val+">"+E2Symbol.val);
                    list.add("goto");
                    list.add("_");
                    ternaryFormulas.add(list);

                    //四元式数量自增1
                    countQuaternion++;

                    list=new ArrayList<>();
                    list.add(String.valueOf(countQuaternion));
                    list.add("goto");
                    list.add("_");
                    ternaryFormulas.add(list);

                    //四元式数量自增1
                    countQuaternion++;
                }
                if(loc==6){
                    Symbol iSymbol=symbolStack.pop();
                    symbol.setVal(iSymbol.getVal());
                    //symbol.setPlace(String.valueOf(pointer));
                    pointer++;

                    //将新属性入栈
                    symbolStack.push(symbol);
                }
                if(loc==7){
                    //属性栈出栈
                    Symbol ESymbol=symbolStack.pop();
                    symbolStack.pop();
                    Symbol iSymbol=symbolStack.pop();

                    String name="T"+countE;
                    countE++;
                    symbol.setVal(name);
                    //symbol.setPlace(String.valueOf(pointer));
                    pointer++;

                    symbol.setBeginCode(ESymbol.getBeginCode());

                    //将新属性入栈
                    symbolStack.push(symbol);

                    list.add(String.valueOf(countQuaternion));
                    list.add(name);
                    list.add(iSymbol.getVal());
                    list.add("=");
                    list.add(ESymbol.getVal());

                    //四元式数量自增1
                    countQuaternion++;

                    System.out.println(list.toString());

                    ternaryFormulas.add(list);
                }
                if(loc==8){
                    //属性栈出栈
                    Symbol E1Symbol=symbolStack.pop();
                    symbolStack.pop();
                    Symbol E2Symbol=symbolStack.pop();

                    //创建新属性，并为新属性的各种属性赋值
                    String name="T"+countE;
                    countE++;
                    symbol.setVal(name);
                    //symbol.setPlace(String.valueOf(pointer));
                    pointer++;

                    //如果E1和E2的beginCode都是未经过定义的，说明该语句为s的第一个四元式
                    if(E1Symbol.getBeginCode()==-1&&E2Symbol.getBeginCode()==-1){
                        symbol.setBeginCode(countQuaternion);
                    }
                    else if(E1Symbol.getBeginCode()!=-1){
                        symbol.setBeginCode(E1Symbol.getBeginCode());
                    }
                    else if(E2Symbol.getBeginCode()!=-1){
                        symbol.setBeginCode(E2Symbol.getBeginCode());
                    }

                    //将新属性入栈
                    symbolStack.push(symbol);

                    //添加新的三地址码进入答案列
                    list.add(String.valueOf(countQuaternion));
                    list.add(name);
                    list.add("=");
                    list.add(E2Symbol.val);
                    list.add("+");
                    list.add(E1Symbol.val);

                    //四元式数量自增1
                    countQuaternion++;

                    System.out.println(list.toString());

                    ternaryFormulas.add(list);
                }
                if(loc==9){
                    //属性栈出栈
                    Symbol E1Symbol=symbolStack.pop();
                    symbolStack.pop();
                    Symbol E2Symbol=symbolStack.pop();


                    //创建新属性，并为新属性的各种属性赋值
                    String name="T"+countE;
                    countE++;
                    symbol.setVal(name);
                    //symbol.setPlace(String.valueOf(pointer));
                    pointer++;


                    if(E1Symbol.getBeginCode()==-1&&E2Symbol.getBeginCode()==-1){
                        symbol.setBeginCode(countQuaternion);
                    }
                    else if(E1Symbol.getBeginCode()!=-1){
                        symbol.setBeginCode(E1Symbol.getBeginCode());
                    }
                    else if(E2Symbol.getBeginCode()!=-1){
                        symbol.setBeginCode(E2Symbol.getBeginCode());
                    }

                    //将新属性入栈
                    symbolStack.push(symbol);

                    //添加新的三地址码进入答案列
                    list.add(String.valueOf(countQuaternion));
                    list.add(name);
                    list.add("=");
                    list.add(E2Symbol.val);
                    list.add("-");
                    list.add(E1Symbol.val);

                    //四元式数量自增1
                    countQuaternion++;

                    System.out.println(list.toString());

                    ternaryFormulas.add(list);
                }
                if(loc==10){
                    Symbol E2Symbol=symbolStack.pop();
                    symbolStack.pop();
                    Symbol E1Symbol=symbolStack.pop();

                    backPatch(E1Symbol.getFalseList(),E2Symbol.getBeginCode());
                    symbol.setVal("E"+countE);
                    countE++;
                    symbol.setBeginCode(E1Symbol.getBeginCode());

                    //
                    symbol.setTrueList(merge(E1Symbol.getTrueList(),E2Symbol.getTrueList()));

                    symbol.setFalseList(E2Symbol.getFalseList());

                    symbolStack.push(symbol);

                }
                if(loc==11){
                    Symbol E2Symbol=symbolStack.pop();
                    symbolStack.pop();
                    Symbol E1Symbol=symbolStack.pop();

                    backPatch(E1Symbol.getTrueList(),E2Symbol.getBeginCode());

                    symbol.setBeginCode(E1Symbol.getBeginCode());

                    symbol.setTrueList(E2Symbol.getTrueList());
                    symbol.setFalseList(merge(E1Symbol.getFalseList(),E2Symbol.getFalseList()));

                    symbolStack.push(symbol);
                }
                if(loc==12){
                    Symbol ESymbol=symbolStack.pop();

                    symbol.setTrueList(ESymbol.getFalseList());
                    symbol.setFalseList(ESymbol.getTrueList());

                    symbolStack.push(symbol);
                }
                if(loc==13){


                    Symbol s1Symbol=symbolStack.pop();
                    symbolStack.pop();
                    Symbol s2Symbol=symbolStack.pop();

                    String name;
                    name="s"+countE;
                    symbol.setVal(name);
                    symbol.setBeginCode(s2Symbol.getBeginCode());
                    symbolStack.push(symbol);
                }
                if(loc==14){
                    symbolStack.pop();
                    Symbol ESymbol=symbolStack.pop();
                    symbolStack.pop();

                    symbol.setTrueList(ESymbol.getTrueList());
                    symbol.setFalseList(ESymbol.getFalseList());
                    symbol.setBeginCode(ESymbol.getBeginCode());
                    symbol.setChain(ESymbol.getChain());
                    symbol.setVal(ESymbol.getVal());
                    symbolStack.push(symbol);
                }
                if(loc==15||loc==16||loc==17||loc==18||loc==19){
                    Symbol iSymbol=symbolStack.pop();
                    symbol.setVal(iSymbol.getVal());
                    //symbol.setPlace(String.valueOf(pointer));
                    pointer++;

                    //将新属性入栈
                    symbolStack.push(symbol);
                }


                int x = Integer.parseInt(state.getTopObjcet());
                int y = conbine.indexOf(pp.get(0));
                System.out.println("GOTO["+x+","+pp.get(0)+"]="+a[x][y]);
                System.out.println("ACTION["+m+","+firstChar+"]="+a[m][n]+"按规则"+a[m][n].substring(1, a[m][n].length())+
                        "将"+mm+"归约到"+pp.get(0)+",弹出栈顶状态"+mm+"、符号"+nn+",且GOTO["+x+","+pp.get(0)+"]="+a[x][y]+
                        "，状态"+a[x][y]+"入栈，符号"+pp.get(0)+"入栈");
                state.push(a[x][y]);
            }
            m = Integer.parseInt(state.getTopObjcet());
            n = conbine.indexOf(firstChar);
            if(n==-1) {
                System.out.println("出错了！！！输入符号中含有非法符号");
                return;
            }

            System.out.println("属性栈中的内容为");
            System.out.println(symbolStack.toString());

        }
        if(a[m][n]=="acc") {
            System.out.println("************步骤"+(++tt)+"*************");
            System.out.print("状态栈：");
            state.output();
            System.out.print("符号栈：");
            analysis.output();
            System.out.print("输入串：");
            System.out.println(str.substring(i));
            System.out.print("执行动作：");
            System.out.println("ACTION["+m+","+firstChar+"]="+a[m][n]+",分析成功");
        }
    }
    //得到分析表
    public void initAnalysisTable(){
        List<List<String>> originalCollect=new ArrayList<List<String>>();//初态项目集
        List<List<List<String>>> collect=new ArrayList<List<List<String>>>();//LR项目集规范族collect
        terminals.add("#");
        ArrayList<String> pro=new ArrayList<String>();
        pro.addAll(productions.get(0));//获取第一个产生式S'→S
        pro.add(1,".");//转换为项目
        pro.add(",");
        pro.add("#");
        originalCollect.add(pro);
        closure(pro,originalCollect);//求 Closure{S'→·S,#}，得初态项目集 originalCollect
        //System.out.println(originalCollect);
        collect.add(originalCollect);//将初态项目集加入到LR项目集规范族collect

        System.out.println("*************GO函数***************");
        conbine.addAll(nonTerminals);
        conbine.addAll(terminals);
        //System.out.println("conbine="+conbine);
        int length=-1,t=0;//从第0个项目集开始遍历
        while(length<collect.size()) {//当项目集规范族collect的大小不再变化时终止
            length=collect.size();//记录项目集规范族collect的变化前的大小
            for(;t<collect.size();t++) {//遍历collect中的项目集即状态
                //对项目集中的每个项目，考察所有的非终结符和终结符输入，看是否能产生新的项目集（状态）
                List<List<String>> mo=collect.get(t);
                for(int i=0;i<conbine.size();i++) {
                    List<List<String>> p=go(t,mo,conbine.get(i));//当状态遇到文法符号conbine.get(i)时采取的动作或者说项目集遇到文法符号得到的项目集
                    if(p.size()>0) {
                        System.out.println("+++++++++++++");
                        System.out.println("GO(I"+t+","+conbine.get(i)+")="+p);

                        if(!collect.contains(p)) {
                            collect.add(p);//将go函数得到的项目集加入到collect中
                        }

                        if(nonTerminals.contains(conbine.get(i))) {
                            a[t][i]=""+collect.indexOf(p);//如果当前文法符号是非终结符标记为：应移入的下一状态。GOTO
                        }else {
                            a[t][i]="S"+collect.indexOf(p);//如果当前文法符号是终结符标记为：把当前输入符号及下一个状态移入分析栈中。ACTION
                        }
                    }
                }
            }
        }
    }
    //文法文本解析与存储
    public void initialize(String filePath) {
        try {
            BufferedReader br = new BufferedReader(new FileReader(filePath));
            String s;
            String[] sss=null;
            for(s=br.readLine();s!=null;s=br.readLine()) {
                if(s.indexOf("{")!=-1) {
                    int begin=s.indexOf("{");
                    int end=s.indexOf("}");
                    sss=s.substring(begin+1, end).split(",");
                }
                //判断每一行是非终结符、终结符、产生式还是开始符号
                if(s.charAt(0)=='V'&&s.charAt(1)=='n') {
                    //存储非终结符
                    for(int i=0;i<sss.length;i++) {
                        nonTerminals.add(sss[i]);
                    }
                }else if(s.charAt(0)=='V'&&s.charAt(1)=='t') {
                    //存储终结符
                    for(int i=0;i<sss.length;i++) {
                        terminals.add(sss[i]);
                    }
                }else if(s.charAt(0)=='P') {
                    //存储产生式
                    for(int i=0;i<sss.length;i++) {

                        String left=sss[i].substring(0, 1);//产生式左部:一个非终结符
                        String[] right=sss[i].substring(sss[i].indexOf(">")+1).split("\\|");//某个产生式左部对应的产生式右部集合
                        for(int j=0;j<right.length;j++) {
                            ArrayList<String> p=new ArrayList<String>();
                            ArrayList<String> pro=new ArrayList<String>();
                            p.add(left);
                            pro.add(left);
                            p.add(right[j]);
                            for(int t=0;t<right[j].length();t++) {
                                pro.add(right[j].substring(t,t+1));
                            }
                            productions.add(pro);
                            pros.add(p);
                        }

                    }
                }else if(s.charAt(0)=='S') {
                    //存储开始符号
                    start=s.substring(2);
                    ArrayList<String> pro=new ArrayList<String>();
                    pro.add("S'");
                    pro.add(start);
                    productions.add(0, pro);
                }

                sss=null;
            }
            br.close();
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
    //文法输出
    public void output() {
        System.out.println("非终结符有");
        for(int i=0;i<nonTerminals.size();i++) {
            System.out.println(nonTerminals.get(i));
        }
        System.out.println("终结符有");
        for(int i=0;i<terminals.size();i++) {
            System.out.println(terminals.get(i));
        }
        System.out.println("产生式有");
        for(int i=0;i<productions.size();i++) {
            System.out.println(productions.get(i));

        }
        System.out.println("开始符号有");
        System.out.println(start);
    }
    //定义单个项目item的闭包函数
    public void closure(List<String> item,List<List<String>> result) {
        //System.out.println("result***"+result);
        int loc=item.indexOf(".");
        //如果当前项目是A→α·Bβ,a的形式
        int dot = item.indexOf(",");
        if(loc<dot-1 && nonTerminals.contains(item.get(loc+1))) {
            String m=item.get(loc+1);
            //如果期待的下一个符号是非终结符，循环遍历productions中的每一条规则
            for(int i=0;i<productions.size();i++) {
                ArrayList<String> pro=new ArrayList<String>();
                pro.addAll(productions.get(i));
                //如果产生式是B→γ的形式
                if(m.equals(pro.get(0))) {
                    pro.add(1, ".");
                    List<String> tem = item.subList(loc+2,item.size());
                    List<String> right = new ArrayList<String>();
                    right.addAll(tem);
                    right.remove(",");//得到βa
                    List<String> firstSet = new ArrayList<String>();
                    findFirstSet(right, firstSet);//得到FIRST(βa)
                    pro.add(",");
                    pro.addAll(firstSet);//将first集加入到B→.γ对应的项目中用，分隔，

                    //System.out.print(pro.subList(0, pro.indexOf(",")).toString().equals(item.subList(0, dot).toString()));
                    //System.out.println(item+"->"+pro);

                    //如果该状态已经存在该项目，则跳过
                    if(result.contains(pro) || pro.subList(0, pro.indexOf(",")).toString().equals(item.subList(0, dot).toString())) {continue;}
                    result.add(pro);//将B→.γ，FIRST(βa)对应的项目加入到闭包集合中
                    if(nonTerminals.contains(pro.get(2))){
                        closure(pro,result);//如果γ的第一个符号是非终结符，递归查找pro的闭包函数
                    }

                }
            }
        }
    }
    //First集
    public void findFirstSet(List<String> right,List<String> first){
        //System.out.println(right);
        String single=right.get(0);
        if(terminals.contains(single) && !first.contains(single)) {
            first.add(single);
        }else if(single.equals("ε")) {
            right=right.subList(1, right.size());
            findFirstSet(right, first);
        }else {
            //说明此产生式右部首字符是一个不同于左部的非终结符
            for(int i=0;i<productions.size();i++) {
                ArrayList<String> pro =new ArrayList<String>();
                pro.addAll(productions.get(i));
                if(single.equals(pro.get(0)) && !single.equals(pro.get(1))) {
                    findFirstSet(pro.subList(1, pro.size()), first);
                }
            }
        }
    }
    //定义当输入文法符号时项目集的GO函数
    public List<List<String>> go(int t,List<List<String>> items,String m) {
        List<List<String>> resultList = new ArrayList<List<String>>();//存储当输入符号m时items对应的项目集
        //循环遍历项目集中的每个项目
        for(int i=0;i<items.size();i++) {
            List<String> list=new ArrayList<String>();
            list.addAll(items.get(i));
            int loc=list.indexOf(".");
            int dot = list.indexOf(",");

            if(loc<dot-1) {
                String n=list.get(loc+1);//期待的下一个符号
                if(n.equals(m)) {//如果期待的下一个符号与当前文法符号一样
                    //System.out.println(items+":"+loc);
                    list.set(loc, n);
                    list.set(loc+1, ".");
                    if(!resultList.contains(list))
                        resultList.add(list);
                    closure(list,resultList);//求当前项目的闭包集合并加入到re中
                }
            }else if(loc==(dot-1) ) {//如果当前项目是可归约的
                //System.out.println(loc+"*************"+dot);
                int o = terminals.indexOf(m);
                List<String> searchWord = list.subList(dot+1, list.size());//得到可归约项目的搜索符号
                list = list.subList(0, loc);
                //如果当前项目是S'->S,# 时，表示此时为可接受状态，记录到分析表中，标记为：可接受
                if(list.equals(productions.get(0))) {
                    //System.out.println(list+","+m);
                    if(o==terminals.size()-1) {
                        a[t][o+nonTerminals.size()]="acc";
                    }
                }else {
                    //查找可归约项目对应的规则
                    for(int j=1;j<productions.size();j++) {//查找可归约项目对应的规则
                        if(list.equals(productions.get(j))) {
                            if(o>=0 && searchWord.contains(m)) {
                                a[t][o+nonTerminals.size()]="r"+j;//记录到分析表中，标记为：可按第j条规则归约
                            }
                            break;
                        }
                    }
                }
            }
        }
        return resultList;
    }


}
